<template>
  <div v-bind:id="gridsterId">

    <template v-if="outEdit">
      <div class='gridster' width="100%" height="90%" :style="graphsForm.style">
        <ul></ul>
      </div>
    </template>

    <el-button-group v-if="editable" id="graphEditButtonGroup">
      <el-button type="success" icon="plus" @click="createGraph()" size='small'>新增图形</el-button>
      <el-button type="primary" icon="check" @click="reloadGraph()" size='small'>重置画布</el-button>
      <el-button type="primary" icon="check" @click="saveGraphs()" size='small'>保存设计</el-button>
    </el-button-group>

    <el-tabs v-if="editable" v-model="activeName">
      <el-tab-pane label="图形设计" name="first" style="padding:5px">

        <div class='gridster' width="100%" height="90%" :style="graphsForm.style">
          <ul></ul>
        </div>

      </el-tab-pane>
      <el-tab-pane label="基础信息" name="second" style="padding:5px">
        <el-form :rules="graphsRules" :model="graphsForm" ref="graphsForm" label-width="100px" class="demo-ruleForm">
          <el-form-item label="图形集类型" prop="grsType">
            <el-select v-model="graphsForm.grsType">
              <el-option v-for="item in graphClassify" :label="item.label" :value="item.value" :key="item.id">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="图形集名称" prop="grsName">
            <el-input v-model="graphsForm.grsName"></el-input>
          </el-form-item>
          <el-form-item label="图形集编号" prop="grsNo">
            <el-input v-model="graphsForm.grsNo"></el-input>
          </el-form-item>
          <el-form-item label="图形参数" prop="params">
            <el-input type="textarea" v-model="graphsForm.params"></el-input>
          </el-form-item>
          <el-form-item label="图形样式" prop="style">
            <el-input type="textarea" v-model="graphsForm.style"></el-input>
          </el-form-item>
          <el-form-item label="备注" prop="remark">
            <el-input type="textarea" v-model="graphsForm.remark"></el-input>
          </el-form-item>
        </el-form>
      </el-tab-pane>
    </el-tabs>
    <template v-else>
      <template v-if="grapshListVisible">

        <el-select multiple filterable v-model="activeGraphs" style="width:100%;margin-bottom:5px">
          <el-option v-for="(item,i) in graphsList" :key="item" :label="item" :value="item">
          </el-option>
        </el-select>

        <div id="main" class="scrollBar">
          <div class="box" v-for="(item,i) in activeGraphs">
            <h4>{{item}}</h4>
            <charter :parentDesignerData="parentDesignerData" :charterId="i+'_'+gridsterId+'_item'" :charterStyle="graphsForm.style" :inputParams="inputParams" :thisParams="graphsForm.params" :thisParamKey="item"></charter>
          </div>
        </div>

      </template>
      <template v-else>
        <div v-if="!outEdit" class='gridster' width="100%" height="90%" :style="graphsForm.style">
          <ul></ul>
        </div>
      </template>
    </template>

    <el-dialog title="图形信息" :modal=false v-model="dialogItemVisible">

      <el-button icon="check" type="primary" size="small" @click="newGraph()">确定</el-button>
      <el-button icon="close" size="small" @click="dialogItemVisible = false">取消</el-button>

      <el-tabs v-model="activeItemName" @tab-click="tabClick">
        <el-tab-pane label="基础信息" name="first" style="padding:5px" >
          <el-form :model="itemForm" :rules="itemRules" ref="itemForm" label-width="100px" class="demo-ruleForm">
            <el-form-item label="图形名称" prop="chartName">
              <el-input v-model="itemForm.chartName"></el-input>
            </el-form-item>
            <el-form-item label="图形类型" prop="chartType">
              <el-select v-model="itemForm.chartType" placeholder="请选择" @change="loadChartItem">
                <el-option v-for="type in itemTypes" :key="type.id" :label="type.value" :value="type.id">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="自动刷新" prop="refFlag">
              <el-select v-model="itemForm.refFlag">
                <el-option label="是" value="1"></el-option>
                <el-option label="否" value="0"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="刷新间隔" prop="refMs">
              <el-select v-model="itemForm.refMs" clearable>
                <el-option label="0.5秒" value="500"></el-option>
                <el-option label="1秒" value="1000"></el-option>
                <el-option label="5秒" value="5000"></el-option>
                <el-option label="10秒" value="10000"></el-option>
                <el-option label="30秒" value="30000"></el-option>
                <el-option label="1分钟" value="60000"></el-option>
                <el-option label="3分钟" value="180000"></el-option>
                <el-option label="5分钟" value="300000"></el-option>
                <el-option label="10分钟" value="600000"></el-option>
                <el-option label="30分钟" value="1800000"></el-option>
                <el-option label="60分钟" value="3600000"></el-option>
              </el-select>
            </el-form-item>
          </el-form>
        </el-tab-pane>
        <el-tab-pane label="详细配置" name="second" style="padding:5px">
          <el-table :data="getItemData" height='300'>
            <el-table-column property="showName" label="配置项" width="150">
              <template scope="scope">
                <el-popover trigger="hover" placement="top">
                  <p>{{ scope.row.desc }}</p>
                  <div slot="reference" class="name-wrapper">
                    {{ scope.row.showName }}
                  </div>
                </el-popover>
              </template>
            </el-table-column>
            <el-table-column property="value" label="配置值" width="235">
            </el-table-column>
            <el-table-column fixed="right" label="操作">
              <template scope="scope">
                <el-button-group>
                  <el-button type="primary" icon="edit" @click.native.prevent="editItem(scope.$index,getItemData)"></el-button>
                </el-button-group>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
      </el-tabs>

    </el-dialog>

    <el-dialog :title="optionForm.showName" :modal=false v-model="dialogOptionVisible">

      <el-form :model="optionForm" ref="optionForm" label-width="100px" class="demo-ruleForm">
        <el-form-item label="说明">
          <el-input v-model="optionForm.desc" :readonly='true'>
          </el-input>
        </el-form-item>

        <el-form-item label="操作">
          <el-button icon="check" type="primary" @click="dialogOptionVisible = false" size="small">确定</el-button>
        </el-form-item>

        <el-form-item label="数据值（可输入也可从下面数据源选择）" prop="value">
          <el-input type="textarea" :row='3' placeholder="请输入数值或者从数据源选择" v-model="optionForm.value">
          </el-input>
        </el-form-item>
        <el-form-item label="数据源表达式（复制替换到值中）">
          <el-input v-model='keystr'>
          </el-input>
        </el-form-item>
        <el-form-item label="数据源">
          <el-row>
            <el-col :span="24">
              <el-table :data="dsData" height='200' :highlight-current-row=true @current-change='dsSelectChange'>
                <el-table-column property="dsName" label="数据主项（点击主项获取细项）"></el-table-column>
                </el-table-column>
              </el-table>
            </el-col>
            <el-col :span="24">
            </el-col>
            <el-col :span="24">
              <el-table :data="dsItemData" style="width: 100%" height='200' :highlight-current-row=true @select='dsItemSelectChange' @select-all='dsItemSelectChange'>
                <el-table-column type="selection">
                </el-table-column>
                <el-table-column property="remark" label="数据细项（勾选细项表示从数据源获取数据）"></el-table-column>
              </el-table>
            </el-col>
          </el-row>
        </el-form-item>
      </el-form>
    </el-dialog>

  </div>
</template>
<script>
import api from 'api/graph'
import chartLoader from 'common/graph/chartLoader'
import charter from './charter.vue'
import ResTypeEnum from 'common/resTypeEnum'
import print from 'utils/print.js'

export default {
  components: {
    charter
  },
  name: 'designer',
  props: {
    gridsterId: {
      type: String,
      default: function() {
        return 'mygridster'
      }
    },
    keyMap: {
      type: Object,
      default: function() {
        return {}
      }
    },
    parentDesignerData: {
      type: Object,
      default: function() {
        return {
          grsName: '',
          grsNo: '',
          remark: ''
        }
      }
    },
    inputParams: { //外部传入参数
      type: Object,
      default: function() {
        return {}
      }
    }
  },
  data() {
    var validatRefMs = (rule, value, callback) => {
      if (value === '' && this.itemForm["refFlag"] === '1') {
        callback(new Error('请输入选择刷新间隔'));
      } else {
        if (value != '' && this.itemForm["refFlag"] === '0') {
          this.itemForm["refMs"] = '';
        }
        callback();
      }
    };
    return {
      editable: false,
      outEdit: false,
      dialogItemVisible: false,
      dialogOptionVisible: false,
      activeName: 'first',
      activeItemName: 'first',
      graphsForm: {
        grsName: '',
        grsType: '0',
        grsNo: '',
        remark: ''
      },
      graphsRules: {
        grsName: [{
          required: true,
          message: '请输入图形集名称',
          trigger: 'blur'
        },
        {
          min: 3,
          max: 265,
          message: '长度在 3 到 265 个字符',
          trigger: 'blur'
        }
        ],
        grsNo: [{
          required: true,
          message: '请输入图形集编号',
          trigger: 'blur'
        },
        {
          min: 3,
          max: 265,
          message: '长度在 3 到 265 个字符',
          trigger: 'blur'
        }
        ],
        grsType: [{
          required: true,
          message: '请选择图形集类型',
          trigger: 'blur'
        }]
      },
      itemForm: {
        chartName: '',
        chartType: '',
        refFlag: '0',
        refMs: ''
      },
      itemRules: {
        chartName: [{
          required: true,
          message: '请输入图形名称',
          trigger: 'blur'
        },
        {
          min: 3,
          max: 265,
          message: '长度在 3 到 265 个字符',
          trigger: 'blur'
        }
        ],
        refMs: [{
          validator: validatRefMs,
          trigger: 'blur'
        }],
        chartType: [{
          required: true,
          message: '请选择图形类型',
          trigger: 'blur'
        }]
      },
      itemTypes: [{
        name: '',
        value: ''
      }],
      itemData: [],
      itemTempData: [],
      dsData: [],
      dsItemData: [],
      $currentEditLi: null,
      currentEditGraphsRow: null,
      optionForm: {
        value: ''
      },
      keystr: '',
      gridster: null,
      GridSter: null,
      graphClassify: [],
      nowLoadNo: "",
      graphsList: [],
      activeGraphs: [],
      grapshListVisible: false,
      select: '0'
    }
  },
  computed:{
    getItemData(){
      return this.itemData;
    }
  },
  /**
   * 监听外部属性变化，加载设计器数据
   * @return {[type]} [description]
   */
  watch: {
    parentDesignerData() {
      //清空画布
      this.graphsList = [];
      this.activeGraphs = [];
      this.grapshListVisible = false;

      this.cleanAll();
      //根据获取路由传入的ID获取配置信息
      if (this.parentDesignerData.grsNo) {
        //关联外部传入数据
        this.activeName = 'first';
        this.graphsForm = this.parentDesignerData;
      } else {
        this.graphsForm = {
          grsName: '',
          grsType: '0',
          grsNo: '',
          remark: ''
        };
      }
      var self = this;
      setTimeout(function() {
        self.init();
      }, 500);
    }
  },
  mounted() {
    this.Gridster = require("gridster"); //引入模块，在webpack.base.conf.js中注册的
    var self = this;
    //设置编辑状态
    if (this.keyMap.editable == 'true') {
      this.editable = true;
      //获取可配置图形列表
      this.itemTypes = chartLoader.getLoaderList();
    }
    if (this.keyMap.outEdit == 'true') {
      this.outEdit = true;
      this.editable = false;
    }

    //初始化设计器
    this.init();
    var resizeTimer = null;
    var $resizeObj = ($("section").length > 0) ? $("section") : $("#app");
    $resizeObj.resize(function() {
      //如果界面上已经不存在图形，取消时间监控
      if ($('.gridster').length == 0) {
        $resizeObj.unbind("resize");
        return false;
      }

      if (resizeTimer) clearTimeout(resizeTimer);
      resizeTimer = setTimeout(function() {
        self.init();
      }, 500);
    });

  },
  methods: {
    loadConfig(grsNo) {
      //读取配置信息
      api.getGraphConfig(grsNo).then((response) => {
        if (response.data) {
          var rdata = response.data
          this.graphsForm = rdata;
          this.currentEditGraphsRow = rdata;
          var params = this.graphsForm.params;
          if (!this.editable && params && params != null) {
            this.setGraphsList();
          } else {
            this._loadGridster(eval('' + rdata["widgetData"] + ''));
          }

        }
      }).catch((err) => {
        console.error(err);
      });
    },
    saveGraphs() {
      this.activeName = 'second';
      if (this.$refs['graphsForm']) {
        this.$refs['graphsForm'].validate((valid) => {
          if (valid) {
            this.doSave();
          } else {
            return false;
          }
        });
      } else {
        this.doSave();
      }
    },
    doSave(isMsg) {
      //表单信息
      var formData = this.graphsForm;
      //布局信息
      if (this.gridster) {
        var s = JSON.stringify(this.gridster.serialize());
        formData["widgetData"] = s;
      }

      api.saveGraphs(formData).then((response) => {
        //同步表单数据（主要是新增的是获取新的ID）
        this.graphsForm = response.data;
        //广播一次保存成功事件
        this.$emit('graphsSave', {});
        if (this.editable || isMsg) {
          this.$message({
            showClose: true,
            message: '保存成功！'
          });
          this.activeName = 'first';
        }
      }).catch((err) => {
        this.$message({
          showClose: true,
          message: "保存失败：" + err.data.errorMsg
        });
        console.error(err);
      });
    },
    editGraph($li) {
      var form = $li.data("form");
      this.activeItemName = 'first';
      this.$currentEditLi = $li;
      //先加载表单信息
      this.itemForm = form;
      this.itemForm.oldChartType = form.chartType;
      this.itemData = chartLoader.getLoaderOption(form.chartType, form.rowdata.rows);
      this.dialogItemVisible = true;
    },
    createGraph() {
      this.activeName = 'first';
      this.activeItemName = 'first';
      this.itemData = [];
      this.itemForm = {
        chartName: '',
        chartType: '',
        refFlag: '0',
        refMs: ''
      };
      this.$currentEditLi = null;
      this.dialogItemVisible = true;
    },
    reloadGraph() {
      this.activeName = 'first';
      this.$confirm('所有的修改都会还原，是否还原画布?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        var row = this.currentEditGraphsRow;
        if (row != null) {
          this._loadGridster(eval('' + row["widgetData"] + ''));
        } else {
          this.cleanAll();
        }
      });

    },
    editItem(index) {
      this.optionForm = this.itemData[index];
      //初始化数据源数据
      api.listDs().then((response) => {
        this.dsData = response.data;
        this.dsItemData = [];
      }).catch((err) => {
        console.error(err);
      });
      this.keystr = '';
      this.dialogOptionVisible = true;
    },
    dsSelectChange(row) {
      if (row && row["params"] && row["params"] != "" && row["params"].length > 0) {
        //数据源存储的params格式为{rowdata:{rows:[],total:1}为了适应easyui,取值的时候要注意
        var data = eval("(" + row["params"] + ")")["rowdata"]["rows"];
        $.grep(data, function(r, i) {
          data[i]["dsNo"] = row["dsNo"];
        });
        this.dsItemData = data;
      }
    },
    dsItemSelectChange(row) {
      if (!row) return false;
      var result = "";
      if (row.length > 0) {
        var dsNo = "";
        var key = "";
        //多选数组
        dsNo = row[0]["dsNo"];
        var itemarray = [];
        $.grep(row, function(item, i) {
          itemarray.push(item["key"]);
        });
        key = itemarray.join(",");
        result = dsNo + "." + key;
      } else {
        result = "";
      }
      this.keystr = "" + result + "";
    },
    tabClick(){
      this.itemData = this.itemTempData
    },
    loadChartItem(chartType) {
      if (chartType && chartType != '') {
        if (this.itemForm.rowdata && this.itemForm.oldChartType == chartType) {
          this.itemTempData = chartLoader.getLoaderOption(chartType, this.itemForm.rowdata["rows"]);
        } else {
          this.itemTempData = chartLoader.getLoaderOption(chartType);
        }
      }
    },
    newGraph() {
      this.$refs['itemForm'].validate((valid) => {
        if (valid) {
          var formData = this.itemForm;
          //配置项信息
          var rows = this.itemData;
          var option = {};
          $.grep(rows, function(n, i) {
            option[n["name"]] = n["value"];
          });
          formData.option = option;
          formData.rowdata = {
            total: rows.length,
            rows: rows
          };
          //添加
          this._addWidget(formData, this.$currentEditLi);
          this.dialogItemVisible = false;
        } else {
          return false;
        }
      });
    },
    setEmptyShow() {
      if (!this.gridster || !this.gridster.hasWidget()) {
        this.$grid.find("ul").html('<div class="empty-graph el-table__empty-block" style="width: ' + this.$grid.actual('width') + 'px;"><span class="el-table__empty-text">' + ((this.editable) ? '暂无图形' : '等待载入') + '</span></div>');
      }
    },
    setGraphsList() {
      var params = this.graphsForm.params;
      var list = [];
      if (params && params != null) {
        var json = eval("(" + params + ")");
        for (var key in json) {
          list.push(key);
        }
        this.graphsList = list;
        this.activeGraphs = list;
      }
      if (this.graphsList.length > 0) {
        this.grapshListVisible = true;
      } else {
        this.grapshListVisible = false;
      }
    },
    init() {
      //初始化加载数据
      if (this.parentDesignerData.grsNo) {
        //关联外部传入数据
        this.graphsForm = this.parentDesignerData;
        this._initContainer();
        this.loadConfig(this.graphsForm.grsNo);
      } else {
        this.$grid = $("#" + this.gridsterId + " .gridster");
        this.setEmptyShow();
      }
      this.graphClassify = ResTypeEnum.getAllGrapshClassify();
    },
    _initContainer() {
      var self = this;
      var $grid = $("#" + this.gridsterId + " .gridster");

      this.$grid = $grid;
      chartLoader.clearAllTimer();
      this.gridster = null;

      //actual为自定义扩展方法，用于获取隐藏元素的宽度，在jquery.gridster.js中注册的
      var winWidth = $grid.actual('width');
      var setWidth = Math.floor((winWidth - 80) / 8);

      $grid.html('<ul></ul>');

      var winHeight = window.innerHeight * (window.innerHeight / window.screen.height);
      var setHeight = Math.floor((winHeight - 160) / 16);
      var setOption = { //通过jquery选择DOM实现gridster
        widget_base_dimensions: [setWidth, setHeight], //模块的宽高 [宽,高]
        widget_margins: [5, 5], //模块的间距 [上下,左右]
        min_cols: 8,
        min_rows: 16,
        resize: {
          enabled: 'true', //允许放缩
          handle: '.resize', //html标签的css类名，按住此标签可以对网格进行放缩
          axes: ['x', 'y', 'both'],
          stop: function(event, ui) { //结束时重新加载数据
            var $li = $(ui.$helper).parents("li");
            self._loadChart($li, $li.data("form"));
            if (!self.editable) { //编辑状态下不需要，避免错误操作
              self.saveGraphs(); //实时保存布局信息
            }
          }
        },
        serialize_params: function($w, wgd) { //$w为要输出位置的网格对象（li），wgd为该网格对象的坐标对象，包括col，row，size                                                     //_x,size_y四个成员
          return {
            col: wgd.col,
            row: wgd.row,
            size_x: wgd.size_x,
            size_y: wgd.size_y,
            form: $w.data("form") //存储的表单信息
          }
        },
        draggable: {
          handle: 'div.graph-header', //头部拖动
          stop: function(event, ui) {
            if (!self.editable) { //编辑状态下不需要，避免错误操作
              self.saveGraphs(); //实时保存布局信息
            }
          }
        }
      };
      var gridster = $grid.find("ul").gridster(setOption).data('gridster');

      this.gridster = gridster;

      $grid.on('click', '.gs-refresh', function() {
        var $li = $(this).parents("li");
        self._loadChart($li, $li.data("form"));
      });

      //点击打印图形
      print.bindEvent($grid)
      if (this.editable) {
        //点击编辑图形
        $grid.on('click', '.gs-edit', function() {
          var $li = $(this).parents("li");
          self.editGraph($li);
        });
        $grid.on('dblclick', "li", function() {
          var $li = $(this);
          self.editGraph($li);
        });
        bindClose();
      }
      if (this.outEdit) {
        bindClose();
      }
      function bindClose() {
        $grid.on('click', '.gs-close', function() {
          self.$confirm('确定删除该图形吗？', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            var $li = $(this).parents("li");
            chartLoader.clearTimer($li); //清除定时器
            gridster.remove_widget($li, null, null); //移除节点
            self.setEmptyShow();
          });
        });
      }
    },
    _loadChart($el, form) {
      $el.data("form", form);

      var params = $.extend({}, this.inputParams);
      chartLoader._init($el, form, params);
      //加载一个图表之后，清除无数据标记
      this.$grid.find(".empty-graph").remove();
    },
    _loadGridster(initData) {

      var self = this;
      this.cleanAll();
      if (initData) {
        //注意：Gridster首字母必须大写；先按row排序，row相同的再按列排序，按排序后的顺序插入data可以保证位置不会偏移
        var data = self.Gridster.sort_by_row_and_col_asc(initData);
        //alert("排序后的widget:\n" + JSON.stringify(data));
        for (var i = 0; i < data.length; i++) {
          var wrapper = this._createLi();
          self.gridster.add_widget(wrapper, data[i].size_x, data[i].size_y, data[i].col, data[i].row);
          self._loadChart(wrapper, data[i]["form"]);
        }
      }
    },
    _createLi() {
      var wrapper = $('<li></li>');
      wrapper.append('<a href="javascript:;" class="gs-refresh" title="刷新"><i class="el-icon-refresh"></i></a>');
      //打印按钮
      // let a40 = '<a href="javascript:;" class="gs-print" style="position: absolute;top: 5px;right: 40px;font-size: 10px;display: inline;z-index: 9999" title="打印"><i class="el-icon-document"></i></a>'
      // let a55 = '<a href="javascript:;" class="gs-print" style="position: absolute;top: 5px;right: 55px;font-size: 10px;display: inline;z-index: 9999" title="打印"><i class="el-icon-document"></i></a>'
      let a40 = print.createElement(40)
      let a55 = print.createElement(55)
      let bool = true
      //是否可以编辑
      if (this.editable) {
        wrapper.append('<a href="javascript:;" class="gs-edit" style="display: inline;" title="编辑"><i class="el-icon-edit"></i></a>' +
          '<a href="javascript:;" class="gs-close" style="" title="关闭"><i class="el-icon-close"></i></a>');
        wrapper.append(a55)
        bool = false
      }
      if (this.outEdit) {
        wrapper.append('<a href="javascript:;" class="gs-close" style="" title="关闭"><i class="el-icon-close"></i></a>');
      }
      if(bool){
        wrapper.append(a40)
      }
      //添加内容模块
      wrapper.append('<div class="chart" style="height: 100%;width: 100%;text-align:center">' +
        '<div class="graph-header" style="cursor:move"></div>' +
        '<div class="graph-bodyer"></div>' +
        '<div class="graph-footer"></div></div>');
      return wrapper;
    },
    _addWidget(form, $li) {
      //添加节点
      if (!$li) {
        $li = this._createLi();
        if (!this.gridster) {
          this._initContainer();
        }
        this.gridster.add_widget($li, 1, 5);
      }
      this._loadChart($li, form);
    },
    cleanAll() {
      chartLoader.clearAllTimer(); //清除定时器
      if (this.gridster) {
        this.gridster.remove_all_widgets(null);
        this.setEmptyShow();
      }
    }
  }
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "../../assets/sass/mixin.scss";
.scrollBar {
  float: left;
  width: 100%;
  height: 80vh;
  overflow-x: hidden;
  overflow: auto;
  @include scrollBar;
}

.box {
  display: inline-block;
  width: 45%;
  padding: 15px;
  margin: 5px;
  background: whitesmoke;
}

.box div {
  min-width: 20vw;
  min-height: 30vh;
}

.box h4 {
  margin-top: -10px;
  margin-left: 0px;
}
</style>
